#include "Scene.hpp"

using namespace aer;


void Scene::init()
{
  // ==========
  // == Cube ==
  // ==========
  cubes.program.generate();
    cubes.program.addShader( Program::VERTEX_SHADER,   "PassThrough.Vertex");
    cubes.program.addShader( Program::FRAGMENT_SHADER, "PassThrough.Fragment");
  AER_CHECK( cubes.program.link() );
  
  cubes.mesh.init( 10.0f );
  
  
  // ============
  // == Lights ==
  // ============
  //  
  
}

void Scene::update()
{
}

void Scene::render(int target, Data& data)
{ 
  if (target & OPAQUE)      renderOpaque(data);
  if (target & DECALS)      renderDecals(data);
  if (target & TRANSPARENT) renderTransparent(data);
}


void Scene::renderOpaque(Data& data)
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );  
  
  //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  
  glEnable( GL_DEPTH_TEST );
    glDepthMask( GL_TRUE );
  
  glEnable( GL_CULL_FACE );
    glCullFace( GL_BACK );
  
  
  const Matrix4x4 &viewProj   = data.viewer.camera->getViewProjectionMatrix();
  const Matrix4x4 &viewMatrix = data.viewer.camera->getViewMatrix();
  
  Matrix4x4 mvp;
  Matrix3x3 normalView;
  
  
  // =============
  // == Skydome ==
  // =============
  // todo
  
  // ===========
  // == Cubes ==
  // ===========
  cubes.program.bind();  
  
const int kNumCube = 50;
float delta = 1.f/(kNumCube-1);
float radius = 90.f;
for (int i=0; i<kNumCube; ++i)
for (int j=0; j<4; ++j)
{
  
    Matrix4x4 model = glm::translate( Matrix4x4(1.0f), Vector3( i*12, j*12, 0));
    // Here model == normal == identity
    mvp = viewProj * model;
    normalView = Matrix3x3(viewMatrix * model);
    
    cubes.program.setUniform( "uModelViewProjMatrix", mvp);
    cubes.program.setUniform( "uNormalViewMatrix", normalView);
    
    cubes.program.setUniform( "uEnableTexturing", false);
    cubes.program.setUniform( "uColor", 1.0f, 1.0f, 1.0f);
    
    cubes.mesh.draw();//
    //cubes.mesh.drawInstances( cubes.mesh.numInstances );
}
  cubes.program.unbind();
  
  
  CHECKGLERROR();
}

void Scene::renderDecals(Data& data)
{
  // render decals objects (TODO)
}

void Scene::renderTransparent(Data& data)
{
  // render blended objects / effects (TODO)
}
